/*
author:杨文超
email:yangwenchao@keynection.cn
*/
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#include "geminai_modem_dce.h"
#include "sdkconfig.h"

/*
Result Code from DCE
*/
#define MODEM_RESULT_CODE_SUCCESS "OK"              /* Acknowledges execution of a command */
#define MODEM_RESULT_CODE_CONNECT "CONNECT"         /* A connection has been established */
#define MODEM_RESULT_CODE_RING "RING"               /* Detect an incoming call signal from network */
#define MODEM_RESULT_CODE_NO_CARRIER "NO CARRIER"   /* Connection termincated or establish a connection failed */
#define MODEM_RESULT_CODE_ERROR "ERROR"             /* Command not recognized, command line maximum length exceeded, parameter value invalid */
#define MODEM_RESULT_CODE_NO_DIALTONE "NO DIALTONE" /* No dial tone detected */
#define MODEM_RESULT_CODE_BUSY "BUSY"               /* Engaged signal detected */
#define MODEM_RESULT_CODE_NO_ANSWER "NO ANSWER"     /* Wait for quiet answer */

/*
Specific Timeout Constraint, Unit: millisecond
*/
/*
int "Timeout (ms) for common AT command"
*/
#define MODEM_COMMAND_TIMEOUT_DEFAULT     2000
/*
int "Timeout (ms) for getting operator status"
*/
#define MODEM_COMMAND_TIMEOUT_OPERATOR    6000
/*
int "Timeout (ms) for reset command"
*/
#define MODEM_COMMAND_TIMEOUT_RESET       6000
/*
int "Timeout (ms) for changing working mode"
*/
#define MODEM_COMMAND_TIMEOUT_MODE_CHANGE 10000
/*
int "Timeout (ms) for power down"
*/
#define MODEM_COMMAND_TIMEOUT_POWEROFF    1000

/*
Strip the tailed "\r\n"

@param str string to strip
@param len length of string
*/
static inline void strip_cr_lf_tail(char *str, uint32_t len)
{
    if (str[len - 2] == '\r') {
        str[len - 2] = '\0';
    } else if (str[len - 1] == '\r') {
        str[len - 1] = '\0';
    }
}

/*
Synchronization

@param[in] dce     Modem DCE object
@param[in] param   None
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_sync(esp_modem_dce_t *dce, void *param, void *result);

/*
Enable or not echo mode of DCE

@param dce Modem DCE object
@param[in] param   bool casted to (void*): true to enable echo mode, false to disable echo mode
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_set_echo(esp_modem_dce_t *dce, void *param, void *result);

/*
Store current parameter setting in the user profile

@param[in] dce     Modem DCE object
@param[in] param   None
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_store_profile(esp_modem_dce_t *dce, void *param, void *result);

/*
Set flow control mode of DCE in data mode

@param[in] dce     Modem DCE object
@param[in] param   esp_modem_flow_ctrl_t casted to (void*): flow control mode
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_set_flow_ctrl(esp_modem_dce_t *dce, void *param, void *result);

/*
Define PDP context
Packet Data Protocol 分组数据协议
PDP（‌Packet Data Protocol）‌：‌这是GPRS（‌通用分组无线服务）‌中的一个协议，‌
用于建立和管理数据连接。‌在GPRS网络中，‌PDP上下文（‌Context）‌的建立是连接Internet的第一步，‌
它涉及到指定接入点（‌APN）‌、‌连接类型（‌IP或PPP）‌等设置，‌为后续的数据传输提供了必要的软硬件环境

@param[in] dce     Modem DCE object
@param[in] param   esp_modem_dce_pdp_ctx_t type defining PDP context
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_set_pdp_context(esp_modem_dce_t *dce, void *param, void *result);

/*
Hang up

@param[in] dce     Modem DCE object
@param[in] param   None
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_hang_up(esp_modem_dce_t *dce, void *param, void *result);

/*
Signal strength structure used as a result to esp_modem_dce_get_signal_quality() API
*/
typedef struct esp_modem_dce_csq_ctx_s {
    int rssi;             // Signal strength indication
    int ber;              // Channel bit error rate
} esp_modem_dce_csq_ctx_t;

/*
Get signal quality

@param[in] dce     Modem DCE object
@param[in] param   None
@param[out] result esp_modem_dce_csq_ctx_t type returning rssi and ber values

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
 */
esp_err_t esp_modem_dce_get_signal_quality(esp_modem_dce_t *dce, void *param, void *result);

/*
Voltage status structure used as a result to esp_modem_dce_get_battery_status() API
*/
typedef struct esp_modem_dce_cbc_ctx_s {
    int battery_status;     // current status in mV
    int bcs;                // charge status (-1-Not available, 0-Not charging, 1-Charging, 2-Charging done)
    int bcl;                // 1-100% battery capacity, -1-Not available
} esp_modem_dce_cbc_ctx_t;

/*
Get battery status

@param[in] dce     Modem DCE object
@param[in] param   None
@param[out] result esp_modem_dce_cbc_ctx_t type returning battery status and other fields if available

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_get_battery_status(esp_modem_dce_t *dce, void *param, void *result);

/*
Get DCE module IMEI number
IMEI：国际移动设备识别码 （International Mobile Equipment Identity）。
由15位数字组成，全球唯一ID，用来区别每一部移动通信设备。与手机是绑定关系。
第一部分 TAC，Type Allocation Code，类型分配码。86为中国。

@param[in] dce     Modem DCE object
@param[in] param   size_t of output string length (casted to void*), max size the resultant string
@param[out] result pointer to the string where the resultant IMEI number gets copied (if size param fits)

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_get_imei_number(esp_modem_dce_t *dce, void *param, void *result);

/*
Get DCE module IMSI number
IMSI是相对手机卡而言的国际移动用户识别码（IMSI：International Mobile Subscriber Identification Number），
IMSI共有15位，其结构如：MCC+MNC+MSIN。
 
@param[in] dce     Modem DCE object
@param[in] param   size_t of output string length (casted to void*), max size the resultant string
@param[out] result pointer to the string where the resultant IMSI number gets copied (if size param fits)

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
	 - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_get_imsi_number(esp_modem_dce_t *dce, void *param, void *result);

/*
Get DCE module name

@param[in] dce     Modem DCE object
@param[in] param   size_t of output string length (casted to void*), max size the resultant string
@param[out] result pointer to the string where the resultant module name gets copied (if size param fits)

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_get_module_name(esp_modem_dce_t *dce, void *param, void *result);

/*
Get operator name

@param[in] dce     Modem DCE object
@param[in] param   size_t of output string length (casted to void*), max size the resultant string
@param[out] result pointer to the string where the resultant operator name gets copied (if size param fits)

@return esp_err_t
	 - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_get_operator_name(esp_modem_dce_t *dce, void *param, void *result);

/*
Switch to data mode

@param[in] dce     Modem DCE object
@param[in] param   None
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_set_data_mode(esp_modem_dce_t *dce, void *param, void *result);

/*
Resume the data mode when PPP has already been started, but switched back to command
mode (typically using the `+++` PPP escape sequence)

@param[in] dce     Modem DCE object
@param[in] param   None
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_resume_data_mode(esp_modem_dce_t *dce, void *param, void *result);

/*
Switch to command mode

@param[in] dce     Modem DCE object
@param[in] param   None
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_set_command_mode(esp_modem_dce_t *dce, void *param, void *result);

/*
Power-down the module

@param[in] dce     Modem DCE object
@param[in] param   None
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_power_down(esp_modem_dce_t *dce, void *param, void *result);

/*
Reset the module

@param[in] dce     Modem DCE object
@param[in] param   None
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_reset(esp_modem_dce_t *dce, void *param, void *result);

/*
@brief Checks if the module waits for entering the PIN

@param[in] dce     Modem DCE object
@param[in] param   None
@param[out] result pointer to bool indicating READY if set to true
                   or the module is waiting for PIN if set to false

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_read_pin(esp_modem_dce_t *dce, void *param, void *result);

/*
Enters the PIN number

@param[in] dce     Modem DCE object
@param[in] param   4 character string pointer to the PIN
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_set_pin(esp_modem_dce_t *dce, void *param, void *result);

/*
Sets the DCE to temporarily use the baudrate specified

@param[in] dce     Modem DCE object
@param[in] param   string pointer to char representation of the baudrate
@param[out] result None

@return esp_err_t
     - ESP_OK on success
     - ESP_FAIL on error
     - ESP_ERR_TIMEOUT if timeout while waiting for expected response
*/
esp_err_t esp_modem_dce_set_baud_temp(esp_modem_dce_t *dce, void *param, void *result);

typedef struct esp_modem_dce_creg_s {
    int urc;            
    int reg_sta;              
    char lac[16] ; 
    char cid[16] ;
    int Act ;
    esp_err_t err_num ;
} esp_modem_dce_creg_t;

typedef struct esp_modem_dce_qnwinfo_s { 
    char net_type[16] ;//网络类型 3g 4g 5g
    char mcc_mnc[16] ;  // mcc mnc 
} esp_modem_dce_qnwinfo_t;


// get lac cid 
esp_err_t esp_modem_dce_get_network_registration(esp_modem_dce_t *dce, void *param, void *result);

esp_err_t esp_modem_dce_get_network_registration_aux(esp_modem_dce_t *dce, void *param, void *result);

// get mcc mnc net
esp_err_t esp_modem_dce_get_network_info(esp_modem_dce_t *dce, void *param, void *result);

esp_err_t esp_modem_dce_get_sim_phone(esp_modem_dce_t *dce, void *param, void *result) ;

